#include<string.h>
#include"FCSV.h"
#define FCSV_FILE_NOT_OPEN 0
#define FCSV_FILE_OPENED 1
#define FCSV_EOF_OFF 0
#define FCSV_EOF_ON 1
#define FCSV_DEFAULT_BUFFER_SIZE 512
static int FCSVOpen(struct __fcsv *pfcsv);
static int FCSVClose(struct __fcsv *pfcsv);
static int FCSVRead(struct __fcsv *pfcsv);
static int FCSVGetCount(struct __fcsv *pfcsv);
static int FCSVGetItemCount(struct __fcsv *pfcsv);
static char *FCSVGetItem(struct __fcsv *pfcsv, int idx);
static int FCSVSetSepChar(struct __fcsv *pfcsv, char cSep);
static int FCSVSetBufferSize(struct __fcsv *pfcsv, int nSize);
LPFCSV FCSVCreate(char *filename) {
LPFCSV pfcsv;
int len;
// FCSV構造体の確保
pfcsv = (LPFCSV)malloc(sizeof(FCSV));
memset(pfcsv, '\0', sizeof(FCSV));
// ファイル名の格納領域の確保
len = strlen(filename);
pfcsv->filename = (char *)malloc(len + 1);
// ファイル名を保存
strcpy(pfcsv->filename, filename);
// 読み込み用バッファの確保
pfcsv->buffer_length = FCSV_DEFAULT_BUFFER_SIZE;
pfcsv->buffer = (char *)malloc(pfcsv->buffer_length);
// SCSV
pfcsv->pscsv = SCSVCreate();
pfcsv->open = FCSVOpen;
pfcsv->close = FCSVClose;
pfcsv->read = FCSVRead;
pfcsv->getCount = FCSVGetCount;
pfcsv->getItemCount = FCSVGetItemCount;
pfcsv->getItem = FCSVGetItem;
pfcsv->setSepChar = FCSVSetSepChar;
pfcsv->setBufferSize = FCSVSetBufferSize;
return pfcsv;
}
int FCSVRelease(LPFCSV pfcsv) {
// ファイルオープン済みの場合は、クローズする。
if(pfcsv->flag_open == FCSV_FILE_OPENED)
pfcsv->close(pfcsv);
// 読み込みバッファの解放
free(pfcsv->buffer);
// ファイル名格納領域の解放
free(pfcsv->filename);
// SCSV
SCSVRelease(pfcsv->pscsv);
// FCSV構造体の解放
free(pfcsv);
return 0;
}
static int FCSVOpen(struct __fcsv *pfcsv) {
// すでにオープンされている場合は、エラー
if(pfcsv->flag_open == FCSV_FILE_OPENED)
return -1;
// ファイルオープン
pfcsv->fp = fopen(pfcsv->filename, "r");
if(pfcsv->fp == NULL)
return -1;
// フラグをオープン済みとする。
pfcsv->flag_open = FCSV_FILE_OPENED;
// 読み込み件数をリセット
pfcsv->record_count = 0;
// EOFフラグをリセット
pfcsv->flag_eof = FCSV_EOF_OFF;
return 0;
}
static int FCSVClose(struct __fcsv *pfcsv) {
// オープンしていない場合はエラー
if(pfcsv->flag_open == FCSV_FILE_NOT_OPEN)
return -1;
// クローズ
fclose(pfcsv->fp);
// フラグをオープン未済に設定
pfcsv->flag_open = FCSV_FILE_NOT_OPEN;
return 0;
}
static int FCSVRead(struct __fcsv *pfcsv) {
char *p;
// オープンされていない場合は、オープンする。
if(pfcsv->flag_open == FCSV_FILE_NOT_OPEN) {
if(pfcsv->open(pfcsv) < 0)
return -1;
}
// EOFの場合は、エラー
if(pfcsv->flag_eof == FCSV_EOF_ON)
return -1;
// 読み込む前にファイル位置を保存
pfcsv->nOffset = ftell(pfcsv->fp);
// 1行読み込む(バッファーの長さより長い場合の対応はまだ)
if(fgets(pfcsv->buffer, pfcsv->buffer_length, pfcsv->fp)) {
pfcsv->record_length = strlen(pfcsv->buffer);
// 改行は消す。
p = strchr(pfcsv->buffer, '\n');
if(p) *p = '\0';
// SCSVによる分解を行う。
pfcsv->pscsv->set(pfcsv->pscsv, pfcsv->buffer);
// 読み込み件数をカウントアップ
pfcsv->record_count++;
}
else {
// EOFの場合の処理
pfcsv->flag_eof = FCSV_EOF_ON;
// 念のため、SCSVをリセット
pfcsv->pscsv->reset(pfcsv->pscsv);
pfcsv->record_length = 0;
return -1;
}
return 0;
}
static int FCSVGetCount(struct __fcsv *pfcsv) {
return pfcsv->record_count; // 読み込み件数を返す。
}
static int FCSVGetItemCount(struct __fcsv *pfcsv) {
return pfcsv->pscsv->getCount(pfcsv->pscsv); // 読み込んだ行の項目数を返す。
}
static char *FCSVGetItem(struct __fcsv *pfcsv, int idx) {
return pfcsv->pscsv->getItem(pfcsv->pscsv, idx); // 指定項目を返す。
}
static int FCSVSetSepChar(struct __fcsv *pfcsv, char cSep) {
return pfcsv->pscsv->setSepChar(pfcsv->pscsv, cSep); // 分解文字を変更
}
static int FCSVSetBufferSize(struct __fcsv *pfcsv, int nSize) {
// 読み込みバッファの大きさを変更する。
free(pfcsv->buffer);
pfcsv->buffer_length = nSize;
pfcsv->buffer = (char *)malloc(pfcsv->buffer_length);
return 0;
} |